package com.sharding.manager;

import com.interceptor.SqlInterceptor;
import org.apache.log4j.Logger;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**分库管理类
 * Created by chenjiansheng on 2017-8-24.
 */
@Component
public class ShardingManager {
    private static Logger log = Logger.getLogger(SqlInterceptor.class);
    /**
     * 获取数据源名
     * @param dbObjName 数据库对象名
     * @param shardingValue 分库值
     * @param ds 数据源
     * @return 数据源名
     * @throws Exception
     */
    @Cacheable(value = "dataSourceName", key = "#shardingValue+'|'+#dbObjName")
    public String getDataSourceName(String dbObjName, String shardingValue, DataSource dataSource) throws Exception   {
        String sResult = "";
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet resultSet = null;
        String sSql = "select t.datasource_name from sharding_datasource_cfg t where t.obj_name=? and t.sharding_value in ('-1',?) order by t.sharding_value desc";
        try{
            conn = dataSource.getConnection();
            stmt = conn.prepareStatement(sSql);
            log.debug("获取数据源名,SQL:"+sSql+",参数为："+dbObjName+","+shardingValue);
            stmt.setString(1,dbObjName);
            stmt.setString(2,shardingValue);
            stmt.executeQuery();// PreparedStatement不能写成stmt.executeQuery(sSql),否则会报错，认为直接执行含有?的SQL而不是执行预编译程序
            resultSet = stmt.getResultSet();
            if (resultSet.next()) {
                sResult = resultSet.getString("datasource_name");
            }
        }catch(Exception ex){
            log.error("获取数据源名失败,SQL:"+sSql+",参数为："+dbObjName+","+shardingValue,ex);
            sResult = null;
        }finally {
            if(resultSet!=null){
                resultSet.close();
            }
            if(stmt!=null){
                stmt.close();
            }
            if(conn!=null){
                conn.close();
            }
        }
        return sResult;
    }
}
